#ifndef EVCONNSVRD_H_
#define EVCONNSVRD_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <stdarg.h>
#include <getopt.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <mm.h>
#include <util.h>
#include <buddy.h>
#include <connbuffer.h>
#include <crc32.h>
#include <log.h>
#include <xml_wrapper.h>
#include <hash.h>
#include <list.h>
#include <encrypt.h>

#include <event2/event.h>
#include <event2/util.h>
#include <event2/thread.h>
#include <event2/listener.h>

#include <lsi.h>

struct connev_t;
struct connev_pool_t;

typedef struct ConnCfg
{
	char cfg_file[64];
	
	size_t mm_max_size;
	size_t mm_unit_size;
	
	int32_t log_type;
	int32_t log_level;
	char log_name[MAX_LOG_NAME_LEN];
	int32_t log_args;

	int32_t multi_thread;

	int32_t tick_interval;

	int32_t kick_timeout;

	char listen_addr_str[64];
	struct sockaddr listen_addr;
	int32_t sock_len;

	lsi_ip_t lsi_ip;
	lsi_ip_t lsi_server_ip;
	lsi_id_t lsi_id;
	int32_t lsi_version;

	char pid_file[64];

	int32_t conn_buffer_size;
	int32_t conn_pool_threshold;

	/* max connections in waiting list */
	int32_t max_conn_in_queue;
	
}ConnCfg;

typedef struct ConnCtx
{
	struct ConnCfg* cfg;
	
	uint16_t ev_address;
	int8_t reload_flag;
	int8_t stop_flag;
	
	uint16_t waiting_conn_count;
	uint16_t connected_conn_count;

	int32_t wait_flag;

	struct list_head waiting_list;
	struct timeval start;
	struct log_t* log;
	struct buddy_t* buddy;
	struct LSI* lsi;

	struct event_base* reactor;
	struct event* timer;
	struct event* stop_event;
	struct event* reload_event;
	struct evconnlistener* listener;
	struct connev_pool_t* connev_pool;
	struct hash_t* connev_table;
}ConnCtx;

extern struct ConnCtx* gCtx;

#define LOG_FATAL(fmt, ...) \
	do{ if(gCtx->log) \
	{ \
		struct timeval now; \
		event_base_gettimeofday_cached(gCtx->reactor, &now); \
		LOG(gCtx->log, ELogLevel_Fatal, &now, fmt, ##__VA_ARGS__); \
	} }while(0)
	
#define LOG_ERROR(fmt, ...) \
	do{ if(gCtx->log) \
	{ \
		struct timeval now; \
		event_base_gettimeofday_cached(gCtx->reactor, &now); \
		LOG(gCtx->log, ELogLevel_Error, &now, fmt, ##__VA_ARGS__); \
	} }while(0)

#define LOG_WARN(fmt, ...) \
	do{ if(gCtx->log) \
	{ \
		struct timeval now; \
		event_base_gettimeofday_cached(gCtx->reactor, &now); \
		LOG(gCtx->log, ELogLevel_Warn, &now, fmt, ##__VA_ARGS__); \
	} }while(0)

#define LOG_DEBUG(fmt, ...) \
	do { if(gCtx->log) \
	{ \
		struct timeval now; \
		event_base_gettimeofday_cached(gCtx->reactor, &now); \
		LOG(gCtx->log, ELogLevel_Debug, &now, fmt, ##__VA_ARGS__); \
	} }while(0)

#define LOG_TRACE(fmt, ...) \
	do {if(gCtx->log) \
	{ \
		struct timeval now; \
		event_base_gettimeofday_cached(gCtx->reactor, &now); \
		LOG(gCtx->log, ELogLevel_Trace, &now, fmt, ##__VA_ARGS__); \
	} }while(0)

#define MAYBE_UNUSED __attribute__((unused)) 

#ifdef __cplusplus
}
#endif

#endif // EVCONNSVRD_H_
